/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.svh.Utils;


import java.io.File;
import java.util.Calendar;
import java.util.Date;
import org.apache.log4j.FileAppender;
import org.apache.log4j.spi.LoggingEvent;

/**
 *
 * @author user
 */
public class DatedFileAppender extends FileAppender{
    // ----------------------------------------------------- Instance Variables

    /**
     * The directory in which log files are created. Wihtout a leading slash,
     * this is relative to the Tomcat home directory.
     */
    private String mdirectory = "logs";
    /**
     * The prefix that is added to log file filenames.
     */
    private String mprefix = "tomcat.";
    /**
     * The suffix that is added to log file filenames.
     */
    private String msuffix = ".log";
    /**
     * The File representation of the directory in which log files are created.
     */
    private File mpath = null;
    /**
     * A calendar object for manipulating dates and times.
     */
    private Calendar mcalendar = null;
    /**
     * The number of milliseconds since 1/1/1970 when tomorrow starts (local
     * time).
     */
    private long mtomorrow = 0L;

    // ----------------------------------------------------------- Constructors
    /**
     * The default constructor will create a Tomcat FileLogger with the
     * following characteristics:
     * <ul>
     * <li>directory: "logs"</li>
     * <li>prefix: "tomcat."</li>
     * <li>suffix: ".log"</li>
     * </ul>
     */
    public DatedFileAppender() {
    }

    /**
     * Creates a new
     * <code>DatedFileAppender</code> with the specified characteristics.
     *
     * @param directory the directory in which log files are created.
     * @param prefix the prefix that is added to log file filenames.
     * @param suffix the suffix that is added to log file filenames.
     */
    public DatedFileAppender(String directory, String prefix, String suffix) {
        mdirectory = directory;
        mprefix = prefix;
        msuffix = suffix;
        activateOptions();
    }

    // ------------------------------------------------------------- Properties
    /**
     * Return the directory in which we create log files.
     */
    public String getDirectory() {
        return mdirectory;
    }

    /**
     * Set the directory in which we create log files.
     *
     * @param directory The new log file directory
     */
    public void setDirectory(String directory) {
        mdirectory = directory;
    }

    /**
     * Return the log file prefix.
     */
    public String getPrefix() {
        return mprefix;
    }

    /**
     * Set the log file prefix.
     *
     * @param prefix The new log file prefix
     */
    public void setPrefix(String prefix) {
        mprefix = prefix;
    }

    /**
     * Return the log file suffix.
     */
    public String getSuffix() {
        return msuffix;
    }

    /**
     * Set the log file suffix.
     *
     * @param suffix The new log file suffix
     */
    public void setSuffix(String suffix) {
        msuffix = suffix;
    }

    // --------------------------------------------------------- Public Methods
    /**
     * Called once all options have been set on this Appender. Calls the
     * underlying FileLogger's start() method.
     */
    public void activateOptions() {
        if (mprefix == null) {
            mprefix = "";
        }
        if (msuffix == null) {
            msuffix = "";
        }
        if ((mdirectory == null) || (mdirectory.length() == 0)) {
            mdirectory = ".";
        }
        mpath = new File(mdirectory);
        if (!mpath.isAbsolute()) {
            String base = System.getProperty("user.dir");
            if (base != null) {
                mpath = new File(base, mdirectory);
            }
        }
        mpath.mkdirs();
        if (mpath.canWrite()) {
            mcalendar = Calendar.getInstance(); // initialized
        }
    }

    /**
     * Called by AppenderSkeleton.doAppend() to write a log message formatted
     * according to the layout defined for this appender.
     */
    public void append(LoggingEvent event) {
        if (this.layout == null) {
            errorHandler.error("No layout set for the appender named [" + name + "].");
            return;
        }
        if (this.mcalendar == null) {
            errorHandler.error("Improper initialization for the appender named [" + name + "].");
            return;
        }
        long n = System.currentTimeMillis();
        if (n >= mtomorrow) {
            // Next line only works with newer (1.4 or so) versions of Java (method is protected in older versions)
            //m_calendar.setTimeInMillis(n);		// set Calendar to current time
            mcalendar.setTime(new Date(n)); // set Calendar to current time
            String datestamp = datestamp(mcalendar); // convert to string "yyyy-mm-dd"
            tomorrow(mcalendar); // set the Calendar to the start of tomorrow
            // Next line only works with newer (1.4 or so) versions of Java (method is protected in older versions)
            //m_tomorrow = m_calendar.getTimeInMillis();	// time in milliseconds when tomorrow starts
            mtomorrow = mcalendar.getTime().getTime(); // time in milliseconds when tomorrow starts
            File newFile = new File(mpath, mprefix + datestamp + msuffix);
            this.fileName = newFile.getAbsolutePath();
            super.activateOptions(); // close current file and open new file
        }
        if (this.qw == null) { // should never happen
            errorHandler.error("No output stream or file set for the appender named [" + name + "].");
            return;
        }
        subAppend(event);
    }

    /**
     * Formats a datestamp as yyyy-mm-dd using a Calendar source object.
     *
     * @param calendar a Calendar containing the date to format.
     *
     * @return a String in the form "yyyy-yy-dd".
     */
    public static String datestamp(Calendar calendar) {
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        StringBuffer sb = new StringBuffer();
        if (year < 1000) {
            sb.append('0');
            if (year < 100) {
                sb.append('0');
                if (year < 10) {
                    sb.append('0');
                }
            }
        }
        sb.append(Integer.toString(year));
        sb.append('-');
        if (month < 10) {
            sb.append('0');
        }
        sb.append(Integer.toString(month));
        sb.append('-');
        if (day < 10) {
            sb.append('0');
        }
        sb.append(Integer.toString(day));
        return sb.toString();
    }

    /**
     * Sets a calendar to the start of tomorrow, with all time values reset to
     * zero.
     *
     * <p>Takes advantage of the fact that the Java Calendar implementations are
     * mercifully accommodating in handling non-existent dates. For example,
     * June 31 is understood to mean July 1. This allows you to simply add one
     * to today's day of the month to generate tomorrow's date. It also works
     * for years, so that December 32, 2004 is converted into January 1,
     * 2005.</p>
     */
    public static void tomorrow(Calendar calendar) {
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH) + 1;
        calendar.clear(); // clear all fields
        calendar.set(year, month, day); // set tomorrow's date
    }
}
